﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ShiQuan.RdpDesktop
{
    /// <summary>
    /// 远程桌面辅助对象
    /// </summary>
    public class RDesktopHelper
    {
        /// <summary>
        /// 获取
        /// </summary>
        /// <returns></returns>
        public static string GetRdesktop(RDesktopInfo rdesktop)
        {
            string password = Protect(rdesktop.Password);
            //创建rdp
            string fcRdp = @"screen mode id:i:1 
                           desktopwidth:i:1280 
                           desktopheight:i:750 
                           session bpp:i:24 
                           winposstr:s:2,3,188,8,1062,721 
                           full address:s:MyServer 
                           compression:i:1 
                           keyboardhook:i:2 
                           audiomode:i:0 
                           redirectdrives:i:0 
                           redirectprinters:i:0 
                           redirectcomports:i:0 
                           redirectsmartcards:i:0 
                           displayconnectionbar:i:1 
                           autoreconnection 
                           enabled:i:1 
                           username:s:" + rdesktop.UserName + @"
                           domain:s:QCH
                           alternate shell:s: 
                           shell working directory:s: 
                           password 51:b:" + password + @"
                           disable wallpaper:i:1 
                           disable full window drag:i:1 
                           disable menu anims:i:1 
                           disable themes:i:0 
                           disable cursor setting:i:0 
                           bitmapcachepersistenable:i:1";
            //return fcRdp;

            StringBuilder info = new StringBuilder();
            info.AppendLine("screen mode id:i:1");
            info.AppendLine("desktopwidth:i:" + rdesktop.DesktopWidth);
            info.AppendLine("desktopheight:i:" + rdesktop.DesktopHeight);
            info.AppendLine("session bpp:i:24");
            info.AppendLine("winposstr:s:2,3,188,8,1062,721");
            info.AppendLine("full address:s:" + rdesktop.FullAddress);
            info.AppendLine("compression:i:1 ");
            info.AppendLine("keyboardhook:i:2");
            info.AppendLine("redirectdrives:i:0 ");
            info.AppendLine("redirectprinters:i:0");
            info.AppendLine("redirectcomports:i:0 ");
            info.AppendLine("redirectsmartcards:i:0 ");
            info.AppendLine("displayconnectionbar:i:1");
            info.AppendLine("autoreconnection");
            info.AppendLine("enabled:i:1");
            info.AppendLine("username:s:" + rdesktop.UserName);
            info.AppendLine("domain:s:QCH");
            info.AppendLine("alternate shell:s: ");
            info.AppendLine("shell working directory:s:");
            info.AppendLine("password 51:b:" + password);
            info.AppendLine("disable full window drag:i:1");
            info.AppendLine("disable menu anims:i:1");
            info.AppendLine("disable themes:i:0 ");
            info.AppendLine("disable cursor setting:i:0");
            info.AppendLine("bitmapcachepersistenable:i:1");

            return info.ToString();
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <returns></returns>
        public static RDesktopInfo GetRdesktop(string fileContent)
        {
            var fileLines = fileContent.Split('\n');
            RDesktopInfo info = new RDesktopInfo();
            foreach (var item in fileLines)
            {
                if (string.IsNullOrEmpty(item))
                    continue;
                string[] fieldValue = item.Split(':');
                if (fieldValue.Length <= 0)
                    continue;

                switch (fieldValue[0])
                {
                    case "desktopwidth":
                        {
                            if (fieldValue.Length == 3)
                                info.DesktopWidth = fieldValue[2];
                            break;
                        }
                    case "desktopheight":
                        {
                            if (fieldValue.Length == 3)
                                info.DesktopHeight = fieldValue[2];
                            break;
                        }
                    case "full address":
                        {
                            if (fieldValue.Length == 3)
                                info.FullAddress = fieldValue[2];
                            break;
                        }
                    case "username":
                        {
                            if (fieldValue.Length == 3)
                                info.UserName = fieldValue[2];
                            break;
                        }
                    case "password 51":
                        {
                            if (fieldValue.Length == 3)
                                info.Password = Unprotect(fieldValue[2]);
                            break;
                        }
                }
            }
            return info;
        }

        /// <summary>
        /// 获取RDP密码
        /// </summary>
        private static string Protect(string pw)
        {
            byte[] secret = Encoding.Unicode.GetBytes(pw);
            byte[] encryptedSecret = ProtectedHelper.Protect(secret);
            string res = string.Empty;
            foreach (byte b in encryptedSecret)
            {
                res += b.ToString("X2"); //转换16进制的一定要用2位 
            }
            return res;
        }

        /// <summary>
        /// RDP密码解密
        /// </summary>
        private static string Unprotect(string pw)
        {
            byte[] secret = Encoding.Unicode.GetBytes(pw);

            byte[] unprotect = ProtectedHelper.Unprotect(secret);
            return Encoding.Unicode.GetString(unprotect);
        }

        /// <summary>
        /// 打开远程桌面
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <param name="admin">用户名</param>
        /// <param name="pw">明文密码</param>
        public static void Open(string ip, string port, string rdpFile)
        {
            //创建bat
            string fcBat = @"mstsc " + rdpFile + " /console /v:" + ip + ":" + port;
            //string batname = "runRdp.bat";
            //FileHelper.SaveFile(batname, fcBat);
            ////创建vbs
            //string vbsname = "runBat.vbs";
            //string fcVbs = @"set ws=WScript.CreateObject(""WScript.Shell"")" + "\r\nws.Run\"runRdp.bat\",0";
            //FileHelper.SaveFile(vbsname, fcVbs);
            //ExecuteVbs(vbsname);

            RDesktopHelper.Mstsc(rdpFile + " /console /v:" + ip + ":" + port);
        }

        /// <summary>
        /// 打开远程桌面
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <param name="admin">用户名</param>
        /// <param name="pw">明文密码</param>
        public static void Open(string ip,string port = "3389", string admin = null, string pw = null)
        {
            var filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "rdesktop");
            if (System.IO.Directory.Exists(filePath) == false)
                System.IO.Directory.CreateDirectory(filePath);

            //创建rdp
            string fcRdp = GetRdesktop(new RDesktopInfo() {FullAddress=ip,UserName=admin,Password=pw});
            string rdpname = System.IO.Path.Combine(filePath, "rdesktop.rdp");
            FileHelper.SaveFile(rdpname, fcRdp);

            //创建bat
            string fcBat = @"mstsc "+rdpname+" /console /v:" + ip + ":" + port;
            //string batname = "runRdp.bat";
            //FileHelper.SaveFile(batname, fcBat);
            ////创建vbs
            //string vbsname = "runBat.vbs";
            //string fcVbs = @"set ws=WScript.CreateObject(""WScript.Shell"")" + "\r\nws.Run\"runRdp.bat\",0";
            //FileHelper.SaveFile(vbsname, fcVbs);
            //ExecuteVbs(vbsname);

            RDesktopHelper.Mstsc(rdpname + " /console /v:" + ip + ":" + port);
        }

        /// <summary>
        /// 调用执行bat文件
        /// </summary>
        /// <param name="batName">文件名</param>
        /// <param name="thisbatpath">路径</param>
        public static void Mstsc(string arguments)
        {
            RDesktopHelper.ProcessStart(System.Environment.SystemDirectory, "mstsc.exe", arguments);
        }
        /// <summary>
        /// 调用执行bat文件
        /// </summary>
        /// <param name="batName">文件名</param>
        /// <param name="thisbatpath">路径</param>
        public static void ProcessStart(string workingDirectory, string fileName, string arguments = "")
        {
            Process proc = null;
            try
            {
                proc = new Process();
                proc.StartInfo.WorkingDirectory = workingDirectory;
                proc.StartInfo.FileName = fileName;
                proc.StartInfo.Arguments = arguments;//this is argument
                proc.StartInfo.RedirectStandardError = false;
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//这里设置DOS窗口不显示，经实践可行
                proc.Start();
                proc.WaitForExit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString());
            }
        }
        /// <summary>
        /// 调用执行bat文件
        /// </summary>
        /// <param name="batName">文件名</param>
        /// <param name="thisbatpath">路径</param>
        public static void ExecuteBat(string batName, string thisbatpath)
        {
            Process proc = null;
            try
            {
                string targetDir = string.Format(thisbatpath);//this is where testChange.bat lies
                proc = new Process();
                proc.StartInfo.WorkingDirectory = targetDir;
                proc.StartInfo.FileName = batName;
                proc.StartInfo.Arguments = string.Format("10");//this is argument
                proc.StartInfo.RedirectStandardError = false;
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//这里设置DOS窗口不显示，经实践可行
                proc.Start();
                proc.WaitForExit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString());
            }
        }

        /// <summary>
        /// 调用执行vbs文件
        /// </summary>
        /// <param name="vbsName">文件名</param>
        public static void ExecuteVbs(string vbsName)
        {
            string path = System.IO.Directory.GetCurrentDirectory() + @"\" + vbsName;
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "wscript.exe";
            startInfo.Arguments = path;
            Process.Start(startInfo);
        }
    }
}
